package com.xxl.job.admin.controller;

import com.xxl.job.core.Constant;

import com.xxl.job.admin.controller.annotation.PermessionLimit;
import com.xxl.job.core.rpc.codec.RpcRequest;
import com.xxl.job.core.rpc.codec.RpcResponse;
import com.xxl.job.core.rpc.netcom.NetComServerFactory;
import com.xxl.job.core.rpc.serialize.HessianSerializer;
import com.xxl.job.core.util.HttpClientUtil;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
/**
 * 调度中心接收Job执行节点的消息
 * 		持续的心跳注册
 * 		主动移除心跳
 * 		Job任务完成后的回调		
 * 
 * Created by xuxueli on 17/5/10.
 */
@Slf4j
@Controller
public class JobApiController {
    
    private final RpcResponse doInvoke(HttpServletRequest request) {
        try {
            // deserialize request
            byte[] requestBytes = HttpClientUtil.readBytes(request);
            if (requestBytes == null || requestBytes.length==0) {
                RpcResponse rpcResponse = new RpcResponse();
                rpcResponse.setError("RpcRequest byte[] is null");
                return rpcResponse;
            }
            
            RpcRequest rpcRequest = (RpcRequest) HessianSerializer.deserialize(requestBytes);
            log.info("admin调度中心收到请求,className :[{}],methodName: [{}]",rpcRequest.getClassName(),rpcRequest.getMethodName());
            
            // invoke
            RpcResponse rpcResponse = NetComServerFactory.invokeService(rpcRequest);
            
            log.info("admin调度中心收到请求处理结束, request: [{}], response : [{}]",rpcRequest,rpcResponse);
            return rpcResponse;
        } 
        catch (Exception e) {
            log.error(e.getMessage(), e);

            RpcResponse rpcResponse = new RpcResponse();
            rpcResponse.setError("Server-error:" + e.getMessage());
            return rpcResponse;
        }
    }
    
    @RequestMapping(Constant.ADMIN_BIZ_MAPPING)
    @PermessionLimit(limit=false)
    public void api(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // invoke
        RpcResponse rpcResponse = this.doInvoke(request);

        // serialize response
        byte[] responseBytes = HessianSerializer.serialize(rpcResponse);

        response.setContentType("text/html;charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);

        OutputStream out = response.getOutputStream();
        out.write(responseBytes);
        out.flush();
    }
}